package cn.max.services;

import cn.incontent.cda.client.common.ArgumentList;
import cn.incontent.fastjson.JSONArray;
import cn.incontent.fastjson.JSONObject;
import cn.max.controllers.ADService;
import cn.max.git.GitUtils;
import cn.max.plat.db.DBManager;
import cn.max.plat.db.DBUtils;
import cn.max.plat.utils.AntHelper;
import com.gitblit.models.PathModel;
import com.gitblit.utils.JGitUtils;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Max-Goday on 15/7/23.
 */
public class RepoService extends ADService {

	public static SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	public void checkout() {

		ArgumentList args = getArgs();
		JSONObject result = new JSONObject();

		result.put("success", GitUtils.checkout(args.get("repo_name"), args.get("commit_id")));

		out(result);

	}

	public void deploy() {

		ArgumentList args = getArgs();

		String repo_name = args.get("repo_name");
		String commit_id = args.get("commit_id");
		String deploy_server_ips = args.get("deploy_server_ips");

		String _FAIL_LIST = "";

		for (String deploy_server_ip : deploy_server_ips.split(", ")) {

			// get target server
			DBObject server = DBUtils.getRepoClusterServerByIP(repo_name, deploy_server_ip);

			// >>>> start to deploy
			if (commit_id != null && GitUtils.checkout(repo_name, commit_id)) {

				if (AntHelper.depoly(repo_name, server) == false) {

					GitUtils.checkout(repo_name, "master");
					_FAIL_LIST += deploy_server_ip + " ";
					return;

				}

				//update cluser server deploy infos
				Map<String, Object> deploy_log = new HashMap<String, Object>();
				BasicDBObject query = new BasicDBObject("repo_name", repo_name).append("ip", deploy_server_ip);

				deploy_log.put("last_deployment_revision", commit_id);
				deploy_log.put("last_deployment_at", SDF.format(new Date()));

				DBUtils.update(DBManager.getClusterRepo(), query, deploy_log);

				//make git ref HEAD to master
				GitUtils.checkout(repo_name, "master");

			} else {

				_FAIL_LIST += deploy_server_ip + " ";

			}
		}

		if (_FAIL_LIST.length() == 0) {

			out(getMsg(true, "Project Deploy At All Server Successfully!"));

		} else {

			out(getMsg(false, "Project Deploy Failed At Server : " + _FAIL_LIST));

		}


	}

	public void getCommitProps() {

		ArgumentList args = getArgs();

		JSONObject result = getMsg(true, null);

		String repo_name = args.get("repo_name");
		String commit_id = args.get("commit_id");

		try {

			Git git = GitUtils.getLocalUpdatedGitRepo(repo_name);

			RevWalk walk = new RevWalk(git.getRepository());

			RevCommit commit = walk.parseCommit(ObjectId.fromString(commit_id));

			//commit_infos
			result.put("commit_id", commit_id);
			result.put("msg", commit.getFullMessage());
			result.put("author", commit.getCommitterIdent().getName() + " - " + commit.getCommitterIdent().getEmailAddress());
			result.put("commit_date", SDF.format((long) commit.getCommitTime() * 1000));

		} catch (Exception e) {
			e.printStackTrace();
			out(getMsg(false, "Error!"));
			return;
		}

		out(result);

	}

	public void getCommitDetail() {

		ArgumentList args = getArgs();

		JSONObject result = getMsg(true, null);

		String repo_name = args.get("repo_name");
		String commit_id = args.get("commit_id");

		int current, rowCount;

		try {
			current = Integer.parseInt(args.get("current"));
			rowCount = Integer.parseInt(args.get("rowCount"));
		} catch (Exception e) {
			current = 1;
			rowCount = 15;
		}

		int _skip_line_count = (current - 1) * rowCount;

		result.put("current", current);
		result.put("rowCount", rowCount);

		JSONArray arr = new JSONArray();

		int total = 0;

		try {

			Git git = GitUtils.getLocalUpdatedGitRepo(repo_name);

			RevWalk walk = new RevWalk(git.getRepository());

			RevCommit commit = walk.parseCommit(ObjectId.fromString(commit_id));

			List<PathModel.PathChangeModel> s = JGitUtils.getFilesInCommit(git.getRepository(), commit);

			for (int i = 0; i < s.size(); i ++) {

				total ++;
				if (total <= _skip_line_count) continue;

				PathModel.PathChangeModel blob = s.get(i);

				JSONObject props = new JSONObject();

				props.put("path", String.valueOf(blob.path));
				props.put("name", String.valueOf(blob.name));
				props.put("size", String.valueOf(blob.size));
				props.put("changetype", String.valueOf(blob.changeType));
				props.put("objectId", String.valueOf(blob.objectId));
				props.put("commitId", commit_id);

				arr.add(props);

			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		result.put("success", true);
		result.put("total", total);
		result.put("rows", arr);

//		try {
//
//			Git git = GitUtils.getLocalUpdatedGitRepo(repo_name);
//
//			RevWalk walk = new RevWalk(git.getRepository());
//
//			RevCommit commit = walk.parseCommit(ObjectId.fromString(commit_id));
//
//			List<PathModel.PathChangeModel> s = JGitUtils.getFilesInCommit(git.getRepository(), commit);
//
//			JSONArray arr = new JSONArray();
//
//			for (int i = 0; i < s.size(); i ++) {
//
//				PathModel.PathChangeModel blob = s.get(i);
//
//				JSONObject props = new JSONObject();
//
//				props.put("path", String.valueOf(blob.path));
//				props.put("name", String.valueOf(blob.name));
//				props.put("size", String.valueOf(blob.size));
//				props.put("changetype", String.valueOf(blob.changeType));
//				props.put("objectId", String.valueOf(blob.objectId));
////				props.put("commitId", blob.commitId);
//
//				arr.add(props);
//
//			}
//
//			//commit_infos
//			result.put("commit_files", arr);
//			result.put("commit_id", commit_id);
//			result.put("msg", commit.getFullMessage());
//			result.put("author", commit.getCommitterIdent().getName() + " - " + commit.getCommitterIdent().getEmailAddress());
//			result.put("commit_date", SDF.format((long) commit.getCommitTime() * 1000));
//
//		} catch (Exception e) {
//			e.printStackTrace();
//			out(getMsg(false, "Error!"));
//			return;
//		}

		out(result);

	}

	public void createRepo() throws Exception {

		ArgumentList args = getArgs();

		if (GitUtils.clone(args.get("repo_url"), args.get("repo_name"), args.get("repo_username"), args.get("repo_password")) == null) {
			out(getMsg(false, "Git Clone Repository Failed!"));
			return;
		}

		BasicDBObject repo = new BasicDBObject("name", args.get("repo_name"))
				.append("ID", new Date().getTime())
				.append("URL", args.get("repo_url"))
				.append("username", args.get("repo_username"))
				.append("password", args.get("repo_password"))
				.append("builder_config_dir", args.get("repo_builder_config_dir"))
				.append("local_dir", GitUtils.LOCAL_REPOSITORY + File.separator + args.get("repo_name"))
				.append("checkout_id", args.get(""))
				.append("des", args.get("message_text"));

		DBManager.getRepositoryRepo().insert(repo);

		out(getMsg(true, ""));

	}

	public void getAllRepo() throws Exception {

		ArgumentList args = getArgs();

		JSONObject result = getMsg(true, null);
		JSONArray arr = new JSONArray();

		DBCursor cursor = DBManager.getRepositoryRepo().find();

		result.put("total", cursor.size());

		while (cursor.hasNext()) {
			JSONObject item = new JSONObject();

			DBObject o = cursor.next();

			item.put("repo_name", o.get("name"));
			item.put("ID", o.get("ID"));
			item.put("repo_url", o.get("URL"));
			item.put("repo_username", o.get("username"));
			item.put("repo_password", o.get("password"));
			item.put("repo_builder_config_dir", o.get("builder_config_dir"));
			item.put("local_dir", o.get("local_dir"));
			item.put("checkout_id", o.get("checkout_id"));
			item.put("des", o.get("des"));

//			item.put("git_id", o.get("ID"));
//			item.put("name", o.get("name"));
//			item.put("url", o.get("repo_url"));

			arr.add(item);

		}

		result.put("result", arr);

		cursor.close();

		out(result);
	}

	public void getRepoLogs() {

		ArgumentList args = getArgs();
		JSONObject result = new JSONObject();

		String Git_Name = args.get("repo");

		Git git = GitUtils.getLocalUpdatedGitRepo(Git_Name);

		int current, rowCount;

		try {
			current = Integer.parseInt(args.get("current"));
			rowCount = Integer.parseInt(args.get("rowCount"));
		} catch (Exception e) {
			current = 1;
			rowCount = 15;
		}

		int _skip_line_count = (current - 1) * rowCount;

		result.put("current", current);
		result.put("rowCount", rowCount);

		JSONArray arr = new JSONArray();

		int total = 0;

		try {
			if (git != null) {
				for (RevCommit rec : git.log().call()) {

					total ++;

					if (total <= _skip_line_count) continue;

					JSONObject item = new JSONObject();

					item.put("c_id", rec.getId().getName());
					item.put("msg", rec.getFullMessage());
					item.put("author", rec.getCommitterIdent().getName() + " - " + rec.getCommitterIdent().getEmailAddress());
					item.put("c_date", SDF.format((long) rec.getCommitTime() * 1000));

					arr.add(item);

				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		result.put("success", true);
		result.put("total", total);
		result.put("rows", arr);

		out(result);

	}
}
